Imports System.Globalization
Imports NUnit.Framework
Imports pixolut.BizBlox

<TestFixture()> Public Class DOTransactionTests

    Public Sub New()
        MyBase.New()
    End Sub

    Private m_userName As String
    Private m_email As String
    Private m_food As String
    Private m_age As Integer
    Private m_price As Double
    Private m_date As DateTime
    Private m_qty As Integer

    <TestFixtureSetUp()> Public Sub globalInit()
        m_userName = "Joe Cincotta"
        m_email = "joe@pixolut.com"
        m_food = "chicken"
        m_age = 32
        m_price = 100.5
        Dim fp As New DateTimeFormatInfo

        m_date = DateTime.ParseExact("2004-07-09 00:00:00Z", "u", CultureInfo.InvariantCulture.DateTimeFormat)
        m_qty = 10
    End Sub

    <SetUp()> Public Sub localInit()
        'do nothing...
    End Sub

    <TearDown()> Public Sub localDestruct()
        Setup.ClearDataSet()
    End Sub

    Private Function CreateStudentTestObject() As Student
        Dim Obj As New Student
        Obj.Age = m_age
        Obj.Name = m_userName
        Obj.Email = m_email
        Return Obj
    End Function

    Private Function CreateFoodTestObject() As Food
        Dim Obj As New Food
        Obj.Name = m_food
        Obj.Price = m_price
        Return Obj
    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Based on the SQL - this table will only accept 50 characters in the name of the food
    ''' - we assign more to ensure the transaction fails.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	15/07/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Private Function CreateFailingFoodTestObject() As Food
        Dim Obj As New Food
        Obj.Name = "hello"
        Obj.Price = m_price
        Obj.FoodID = Nothing
        Return Obj
    End Function


    Private Function CreateLunchOrderTestObject(ByVal foodObj As Food, ByVal studentObj As Student) As LunchOrder
        Dim Obj As New LunchOrder
        Obj.StudentID = studentObj.StudentID
        Obj.FoodID = foodObj.FoodID
        Obj.dt_OrderDate = m_date
        Obj.Quantity = m_qty
        Return Obj
    End Function


    <Test()> Public Sub testCreateWithTransaction()
        Dim trans As New DOTransaction
        Dim sObj As Student = Me.CreateStudentTestObject()
        sObj.Save(trans)
        Dim fObj As Food = Me.CreateFoodTestObject()
        fObj.Save(trans)
        Dim lObj As LunchOrder = Me.CreateLunchOrderTestObject(fObj, sObj)
        lObj.Save(trans)
        trans.Commit()

        Dim sUid As Guid = sObj.StudentID
        Dim fUid As Guid = fObj.FoodID
        Dim lUid As Guid = lObj.LunchOrderID

        sObj = New Student(sUid)
        sObj.Load()
        Assert.AreEqual(sObj.Name, m_userName)
        Assert.AreEqual(sObj.Email, m_email)
        Assert.AreEqual(sObj.Age, m_age)

        fObj = New Food(fUid)
        fObj.Load()
        Assert.AreEqual(fObj.Name, m_food)
        Assert.AreEqual(fObj.Price, m_price)

        lObj = New LunchOrder(lUid)
        lObj.Load()
        Assert.AreEqual(lObj.dt_OrderDate.ToString("u"), m_date.ToString("u"))
        Assert.AreEqual(lObj.Quantity, m_qty)

        Console.WriteLine("Transaction success...")
    End Sub

    <Test(), ExpectedException(GetType(DOException))> Public Sub testFailCreateWithTransaction()
        Dim trans As New DOTransaction
        Dim sObj As Student = Me.CreateStudentTestObject()
        sObj.Save(trans)

        Dim fObj As Food = Me.CreateFailingFoodTestObject()
        fObj.Save(trans)
        Dim lObj As LunchOrder = Me.CreateLunchOrderTestObject(fObj, sObj)
        lObj.Save(trans)

        Dim sUid As Guid = sObj.StudentID
        Dim fUid As Guid = fObj.FoodID
        Dim lUid As Guid = lObj.LunchOrderID

        Try
            Console.WriteLine("Attempt to fail transaction on purpose!")
            trans.Commit()
        Catch ex As Exception
            Console.WriteLine(ex.ToString())
            Console.WriteLine("Assertion: load should throw exception since GUID does not exist.")
            sObj = New Student(sUid)
            sObj.Load()
            Console.WriteLine("The transaction code did not work if you are here!")
            Assert.Fail("Object committed in a failed transaction!")
        End Try
    End Sub

    <Test(), ExpectedException(GetType(DOException))> Public Sub testAttemptRetrieveWithinCreateTransaction()
        Dim trans As New DOTransaction
        Dim sObj As Student = Me.CreateStudentTestObject()
        sObj.Save(trans)
        Dim fObj As Food = Me.CreateFoodTestObject()
        fObj.Save(trans)

        Dim sUid As Guid = sObj.StudentID
        Dim xObj As New Student(sUid)
        xObj.Load()
        Console.WriteLine("Assertion: load should throw exception since GUID does not exist.")
        Console.WriteLine("The transaction code did not work if you are here!")
        Assert.Fail("Object committed and retrieved mid transaction!")
    End Sub

    <Test()> Public Sub testAttemptNewTransaction()
        Dim trans As New DOTransaction(CInt(IsolationLevel.Serializable))
        Dim sObj As New Student()
        sObj.Name = m_userName
        sObj.Email = m_email
        sObj.Age = m_age
        sObj.Save()

        Dim uid As Guid = sObj.StudentID

        Dim newStudent As New Student(uid)
        newStudent.Load()
        newStudent.Name = "Chris Thomas"
        newStudent.Save(trans)
        trans.Commit()

        Dim sObj3 As New Student(uid)
        sObj3.Load()
        Dim final As String = sObj3.Name

        Console.WriteLine("Original Name: " + m_userName)
        Console.WriteLine("After Commit: " + final)
        Assert.AreNotEqual(final, m_userName)
    End Sub

End Class
